# Copyright 2022 Flant JSC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

name: Changelog by milestone
on:
  issues:
    types:
      - "milestoned"
      # We don't track "demilestoned" event type. If we did, changing a milestone would always
      # trigger duplicating workflows one of which would fail due to concurrent updates of the same
      # changelog branch. We hope, that milestones change to other milestones, and are not removed
      # at all. To update changelog, one should call `/changelog` command in a changelog PR.
      # - "demilestoned"
jobs:
  condition_check:
    name: Check conditions
    runs-on: ubuntu-latest
    steps:
      - name: Check PR
        id: pr
        uses: actions/github-script@v5.2.0
        with:
          result-encoding: string
          script: |
            // See
            //    https://github.com/actions/github-script
            //    https://github.com/actions/toolkit/blob/main/packages/github/src/context.ts
            //    https://github.com/actions/toolkit/blob/main/packages/github/src/interfaces.ts#L15

            const number = context.issue.number

            if (!context.payload.issue.pull_request) {
              core.notice(`Issue #${number} is not a pull request. Skip changelog regeneration.`)
              return "skip"
            }

            if (context.payload.action !== 'milestoned' && context.payload.action !== 'demilestoned') {
              // we support only milestoned because of race condition when milestone is changed
              // core.notice(`The PR #${number} payload action is not "milestoned" or "demilestoned", it is "${context.eventName}"`)
              core.notice(`The PR #${number} payload action is not "milestoned", it is "${context.payload.action}". Skip changelog regeneration.`)
              return "skip"
            }

            const { data: pr } = await github.rest.pulls.get({
              owner: context.repo.owner,
              repo: context.repo.repo,
              pull_number: number,
            });

            if (!pr) {
              core.notice(`Issue #${number} is not a pull request. Skip changelog regeneration.`)
              return "skip"
            }

            const isChangelog = pr.labels.some(({ name }) => name === 'changelog')
            if (isChangelog) {
              core.notice(`Skipped the changelog PR #${number}`)
              return "skip"
            }

            if (pr.state !== 'closed') {
              core.notice(`The PR #${number} is open (not closed). Skip changelog regeneration.`)
              return "skip"
            }

            if (!pr.merged) {
              core.notice(`The PR #${number} is not merged. Skip changelog regeneration.`)
              return "skip"
            }

            core.notice('OK to regenerate changelogs')
            return "ok"
    outputs:
      ok: ${{ steps.pr.outputs.result }}

  milestones:
    needs: condition_check
    if: needs.condition_check.outputs.ok == 'ok'
    name: Open Milestones
    runs-on: ubuntu-latest
    steps:
      - name: Find Open Milestones
        id: milestones
        env:
          GITHUB_TOKEN: ${{ secrets.CHANGELOG_ACCESS_TOKEN }}
        # https://docs.github.com/en/rest/reference/issues#milestones
        run: |
          milestones="$(gh api 'repos/${{ github.repository }}/milestones?state=open&per_page=100')"

          count="$(echo $milestones | jq '. | length')"

          echo "list=${milestones}" >> $GITHUB_OUTPUT
          echo "count=${count}" >> $GITHUB_OUTPUT

    outputs:
      list: ${{ steps.milestones.outputs.list }}
      count: ${{ steps.milestones.outputs.count }}

  changelogs:
    if: needs.milestones.outputs.count > 0
    name: Changelog ${{ matrix.milestone.title }}
    runs-on: ubuntu-latest
    needs: milestones
    strategy:
      max-parallel: 1
      matrix:
        milestone: ${{ fromJSON( needs.milestones.outputs.list ) }}
    steps:
      - name: Checkout
        uses: actions/checkout@v3.5.2

      - name: Create changelog
        uses: ./.github/actions/milestone-changelog
        with:
          milestone: ${{ toJSON( matrix.milestone ) }}
          token: ${{ secrets.CHANGELOG_ACCESS_TOKEN }}
